'''
Created on 09/04/2009

@author: eh01
'''
from im import xmlconstants
from im.ds import dsconstants, dsofactory
from im.ds.dso import DSO
from im.ds.dsstub import DSStub
from im.ds.dst import DST
from im.event import eventconstants
from im.event.event import Event
from im.event.eventhandler import BaseEventHandler
from im.event.eventmanager import EventManager
from im.logindecorator import loginRequired
import httplib
import datetime
import re

class HTTPRequestPUTNodeMessageHandler(BaseEventHandler):

    @loginRequired
    def do(self, data):
        dso = data
        http_request = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST).get_literal()
        lock = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_LOCK).get_literal()
        http_request_header_content_type = dso.get_dst(subject=dsconstants.SUBJECT_HTTP_REQUEST_HEADER,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST_HEADER_CONTENT_TYPE).get_literal()
        body = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST_BODY).get_literal()                    
        
        dst1 = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_CONTENT_TYPE,
            literal=http_request_header_content_type)

        dst2 = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_TIMESTAMP,
            literal=datetime.datetime.now())

        dst3 = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_BODY,
            literal=body)
                        
        message_dso = DSO([dst1, dst2, dst3])
        
        ds_stub = DSStub()
        message_id = None
        
        # see if the message is a new message, or replacing a exisiting one
        matches_new_message = re.match('/node/(\d+)$', http_request.path)
        matches_replace_message = re.match('/node/(\d+)/(\d+)$', http_request.path)
        
        if matches_new_message:
            node_id = int(matches_new_message.group(1))
        else:
            node_id = int(matches_replace_message.group(1))
            message_id = int(matches_replace_message.group(2))

        # if the destination node is not currently connected then
        # don't add the message
        if ds_stub.is_node_currently_connected(node_id):
            message_id = ds_stub.add_message(node_id=node_id, 
                             message_id=message_id, 
                             message=message_dso)  
            response_body = xmlconstants.XML_VERSION_TAG + \
                            xmlconstants.MESSAGE_TAG_OPENING + \
                            xmlconstants.ID_TAG_OPENING + \
                            str(message_id) + \
                            xmlconstants.ID_TAG_CLOSING + \
                            xmlconstants.MESSAGE_TAG_CLOSING
            # create new dso        
            new_dso = dsofactory.create_dso_for_im_http_response_handler(httplib.FOUND, 
                                                                   xmlconstants.XML_CONTENT_TYPE, 
                                                                   response_body, 
                                                                   http_request, 
                                                                   lock)
            event_type = eventconstants.HTTP_RESPONSE_EVENT_TYPE
        else:
            # if the node is not currently connected, then send a error back
            new_dso = dsofactory.create_dso_for_http_error_handler(httplib.NOT_FOUND, 
                                             '', 
                                             http_request, 
                                             lock)
            event_type = eventconstants.HTTP_ERROR_EVENT_TYPE
            
        event = Event(event_type, new_dso)
        EventManager().add_event(event)